/*******************************************************************************
** 文件名称：gpio.h
** 文件作用：GPIO头文件
** 编写作者：TomFree <付瑞彪>
** 编写时间：2019-12-20
** 文件备注：
**
** 更新记录：
**           2019-12-20 -> 创建文件                                 <Tom Free>
**
**           1 Tab == 4 Spaces     UTF-8     ANSI C Language
*******************************************************************************/
#ifndef __GPIO_H__
#define __GPIO_H__

/* 自定义类型头文件 */
#include "typedef.h"

/*定义与GPIO端口相关的数据类型*/
typedef GM_U8 GPIO_PIN;     /* 引脚编号 0-7 */
typedef GM_U8 GPIO_CONFIG;  /* 端口配置 */
typedef GM_U8 GPIO_LEVEL;	/* 端口电平 */

/* 与输出对应的配置项 */
#define GPIO_LOW    0x00U   /* 低电平 */
#define GPIO_HIGH   0x01U   /* 高电平 */

/* 与输入相应的配置项 */
#define GPIO_FLOAT  0x00U   /* 浮空输入 */
#define GPIO_PULLUP 0x01U   /* 上拉输入 */

/* 输入输出选择配置项 */
#define GPIO_INPUT  0x00U   /* 输入 */
#define GPIO_OUTPUT 0x02U   /* 输出 */

/*GPIO的RAM空间镜像结构*/
typedef struct
{
    GM_REG PIN;	            /* 数据输入寄存器 */
    GM_REG DDR;	            /* 端口方向寄存器 */
    GM_REG PORT;	        /* 数据输出寄存器（上拉电阻使能寄存器） */
} *GPIO;

/* 根据不同的单片机型号来确定IO口组数 */
#if ((CHIP_TYPE == 16) || \
     (CHIP_TYPE == 32) || \
     (CHIP_TYPE == 128))
#define PA      (GPIO)(&PINA)
#endif  /* END */

#if ((CHIP_TYPE == 8)  || \
     (CHIP_TYPE == 48) || \
     (CHIP_TYPE == 88) || \
     (CHIP_TYPE == 168)|| \
     (CHIP_TYPE == 328)|| \
     (CHIP_TYPE == 16) || \
     (CHIP_TYPE == 32) || \
     (CHIP_TYPE == 128))
#define PB      (GPIO)(&PINB)
#define PC      (GPIO)(&PINC)
#define PD      (GPIO)(&PIND)
#endif  /* END */

#if (CHIP_TYPE == 128)
#define PE      (GPIO)(&PINE)
#define PF      (GPIO)(0X60)
#define PG      (GPIO)(&PING)
#endif  /* END */


/********************GPIO操作接口函数***********************/
void        GPIO_DeInit  (GPIO Port);
void        GPIO_PinInit (GPIO Port, GPIO_PIN Pin, GPIO_CONFIG Config);
void        GPIO_PinSet  (GPIO Port, GPIO_PIN Pin, GPIO_CONFIG Config);
GPIO_LEVEL  GPIO_PinGet  (GPIO Port, GPIO_PIN Pin);
void        GPIO_PinTurn (GPIO Port, GPIO_PIN Pin);
void        GPIO_PortInit(GPIO Port, GPIO_CONFIG Config);
void        GPIO_PortRSel(GPIO Port, GPIO_CONFIG Config);
void        GPIO_PortSet (GPIO Port, GPIO_CONFIG Config);
GPIO_CONFIG GPIO_PortGet (GPIO Port);

#if (CHIP_TYPE == 128)
void        GPIOF_PinInit(GPIO_PIN Pin, GPIO_CONFIG Config);
void        GPIOF_PinSet (GPIO_PIN Pin, GPIO_CONFIG Config);
GPIO_LEVEL  GPIOF_PinGet (GPIO_PIN Pin);
void        GPIOF_PinTurn(GPIO_PIN Pin);
#endif  /* CHIP_TYPE == 128 */
/********************GPIO操作接口函数***********************/


#define MACRO_CONCAT2(a, b) a ## b
#define MACRO_ARG21(a, b)   a
#define MACRO_ARG22(a, b)   b

/*****************实现类似51单片机的位操作******************/
#define PIN_DIR(port, pin)      (((GM_BYTE*)(&(((GPIO)port)->DDR)))->MACRO_CONCAT2(bit, pin))
#define PIN_OUT(port, pin)      (((GM_BYTE*)(&(((GPIO)port)->PORT)))->MACRO_CONCAT2(bit, pin))
#define PIN_IN(port, pin)       (((GM_BYTE*)(&(((GPIO)port)->PIN)))->MACRO_CONCAT2(bit, pin))
#define PIN_R(port, pin)        (((GM_BYTE*)(&(((GPIO)port)->PORT)))->MACRO_CONCAT2(bit, pin))
#define PORT_DIR(port)          (((GPIO)port)->DDR)
#define PORT_OUT(port)          (((GPIO)port)->PORT)
#define PORT_IN(port)           (((GPIO)port)->PIN)
#define PORT_R(port)            (((GPIO)port)->PORT)

#define PIN_SETIN (port, pin)   GPIO_PinInit(port, pin, GPIO_INPUT)
#define PIN_SETOUT(port, pin)   GPIO_PinInit(port, pin, GPIO_OUTPUT)
#define PIN_HIGH  (port, pin)   GPIO_PinSet (port, pin, GPIO_HIGH)
#define PIN_LOW   (port, pin)   GPIO_PinSet (port, pin, GPIO_LOW)
#define PIN_REN   (port, pin)   GPIO_PinSet (port, pin, GPIO_PULLUP)
#define PIN_RDIS  (port, pin)   GPIO_PinSet (port, pin, GPIO_FLOAT)
#define PIN_READ  (port,pin)    GPIO_PinGet (port, pin)
/*****************实现类似51单片机的位操作******************/

#endif  /* __GPIO_H__ */
